package com.hmy.infrastructure.service.district;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmy.infrastructure.bo.response.DistrictResponse;
import com.hmy.infrastructure.common.constant.RedisKeyConstant;
import com.hmy.infrastructure.dal.District;
import com.hmy.infrastructure.dal.mapper.DistrictMapper;
import com.hmy.infrastructure.service.IDistrictService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Lyn 宋开放
 * @date 2023-12-20 21:10
 **/
@Service
public class DistrictServiceImpl extends ServiceImpl<DistrictMapper, District> implements IDistrictService {

    private final RedisTemplate<String, Object> redisTemplate;

    public DistrictServiceImpl(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public List<DistrictResponse> getDistrictTree() {
        /*
         判断Redis是否存在行政区划数据
         */
        if (redisTemplate.hasKey(RedisKeyConstant.DISTRICT_CACHE_KEY)) {
            return JSONUtil.toList(JSONUtil.toJsonStr(redisTemplate.opsForValue().get(RedisKeyConstant.DISTRICT_CACHE_KEY)), DistrictResponse.class);
        } else {
            /*
             * 重新组装数据库中查询出来的行政区划数据
             */
            List<District> districts = baseMapper.selectList(Wrappers.lambdaQuery());
            /*
             * 构建树状结构
             */
            List<DistrictResponse> responses = buildDistrictTree(districts);
            /*
             * 设置Redis缓存，一天内过期
             */
            redisTemplate.opsForValue().set(RedisKeyConstant.DISTRICT_CACHE_KEY, JSONUtil.toJsonStr(responses), 1, TimeUnit.DAYS);
            return responses;
        }
    }

    /**
     * 构建行政区划树状结构
     *
     * @param districts 待处理行政区划集合
     * @return 行政区划树状集合
     */
    private List<DistrictResponse> buildDistrictTree(List<District> districts) {
        List<DistrictResponse> responses = new ArrayList<>();
        // 使用递归构建树状结构
        for (District district : districts) {
            DistrictResponse districtResponse = BeanUtil.copyProperties(district, DistrictResponse.class);
            List<DistrictResponse> children = getChildren(district.getId(), districts);

            districtResponse.setChildren(children);
            responses.add(districtResponse);
        }
        return responses;
    }

    /**
     * 递归处理子集数据
     *
     * @param parentId  父级ID
     * @param districts 行政区划集合
     * @return 子集数据
     */
    private List<DistrictResponse> getChildren(Long parentId, List<District> districts) {
        List<DistrictResponse> children = new ArrayList<>();
        for (District district : districts) {
            if (parentId.equals(district.getParentId())) {
                DistrictResponse districtResponse = BeanUtil.copyProperties(district, DistrictResponse.class);
                List<DistrictResponse> subChildren = getChildren(district.getId(), districts);
                districtResponse.setChildren(subChildren);
                children.add(districtResponse);
            }
        }
        return children;
    }

}
